﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using SharedGenomics.Workbench.Core;
using SharedGenomics.Workbench.Services;
using SharedGenomics.Domain;
using SharedGenomics.Domain.Data;

using Rhino.Mocks;
using Rhino.Mocks.Interfaces;

namespace SharedGenomics.Workbench.Tests.Presenters
{
    [TestClass]
    public class OpenGenotypeFilePresenterTests
    {
        //#region Private Members

        //private MockRepository mocks;
        //private IMissingMarkersModel model;
        //private IOpenGenotypeFileView view;
        //private IFileBrowserPresenter fileLoad;
        //private IOpenFileDialog filterListDialog;
        //private IEditUserMarkerPresenter markerEdit;
        //private TestLoginGuard loginGuard;
        //private ISnpService snpService;
        //private IMarkerWatchListParser watchListParser;

        //#endregion

        //#region Setup

        //[TestInitialize]
        //public void Setup()
        //{
        //    this.mocks = new MockRepository();

        //    this.model = this.mocks.DynamicMock<IMissingMarkersModel>();
        //    this.view = this.mocks.DynamicMock<IOpenGenotypeFileView>();
        //    this.fileLoad = this.mocks.DynamicMock<IFileBrowserPresenter>();
        //    this.filterListDialog = this.mocks.StrictMock<IOpenFileDialog>();
        //    this.markerEdit = this.mocks.DynamicMock<IEditUserMarkerPresenter>();
        //    this.loginGuard = new TestLoginGuard();
        //    this.snpService = this.mocks.StrictMock<ISnpService>();
        //    this.watchListParser = this.mocks.StrictMock<IMarkerWatchListParser>();
        //}

        //#endregion

        //#region Constructor Tests

        //[TestMethod]
        //public void ConstructorTest()
        //{
        //    var model = this.mocks.StrictMock<IMissingMarkersModel>();
        //    var view = this.mocks.StrictMock<IOpenGenotypeFileView>();
        //    var fileLoad = this.mocks.StrictMock<IFileBrowserPresenter>();
        //    var watchListDialog = this.mocks.StrictMock<IOpenFileDialog>();
        //    var markerEdit = this.mocks.DynamicMock<IEditUserMarkerPresenter>();
        //    var loginGuard = this.mocks.Stub<ILoginRequiredGuard>();
        //    var snpService = this.mocks.Stub<ISnpService>();
        //    var watchListParser = this.mocks.Stub<IMarkerWatchListParser>();

        //    using (this.mocks.Record())
        //    {
        //        //new presenter should register for all required events
        //        fileLoad.FileOpened += null;
        //        LastCall.IgnoreArguments();

        //        view.FilterListOpened += null;
        //        LastCall.IgnoreArguments();

        //        view.MissingMarkerSelected += null;
        //        LastCall.IgnoreArguments();

        //        model.ListChanged += null;
        //        LastCall.IgnoreArguments();

        //        markerEdit.MarkerUpdated += null;
        //        LastCall.IgnoreArguments();
        //    }

        //    using (this.mocks.Playback())
        //    {
        //        var presenter = new OpenGenotypeFilePresenter(model, view, fileLoad, watchListDialog, markerEdit, loginGuard, snpService, watchListParser);
        //    }
        //}

        //#endregion

        //#region Event Tests

        //#region Genotype File Opened

        //[TestMethod]
        //[Ignore]    //fix file parsing
        //public void GenotypeFileOpenedSuccessful()
        //{
        //    IEventRaiser openedEvent;

        //    using (this.mocks.Record())
        //    {
        //        this.fileLoad.FileOpened += null;
        //        LastCall.IgnoreArguments();
        //        openedEvent = LastCall.GetEventRaiser();

        //        //presenter should try to parse the given file contents, get the missing markers from the service and fill the model with any returned values
        //        Expect.Call(this.fileLoad.FilePath).Return("fileName");

        //        IndividualGenotypeCollection genotypes = new IndividualGenotypeCollection();
        //        genotypes.Markers.Add("marker1");
        //        genotypes.Markers.Add("marker2");
        //        genotypes.Markers.Add("marker3");

        //        //Expect.Call(this.fileParser.ParseGenotypeFile("fileName")).Return(genotypes);

        //        IEnumerable<string> missingMarkers = new[] { "marker1", "marker4" };
        //        Expect.Call(this.snpService.FilterUnavailableMarkers(genotypes.Markers)).Return(missingMarkers);
        //        this.model.LoadMarkers(missingMarkers);
        //    }

        //    using (this.mocks.Playback())
        //    {
        //        var presenter = this.CreatePresenter();

        //        bool loadedEventRaised = false;
        //        presenter.GenotypeFileLoaded += (o, e) => { loadedEventRaised = true; };

        //        openedEvent.Raise(null, null);
        //        Assert.IsTrue(loadedEventRaised);
        //        Assert.AreEqual("fileName", presenter.GenotypeFilePath);
        //        Assert.IsTrue(this.loginGuard.WasCalled);
        //    }
        //}

        //[TestMethod]
        //[Ignore]    //fix file parsing
        //public void GenotypeFileOpenedFile_ParseThrowsException()
        //{
        //    IEventRaiser openedEvent;

        //    using (this.mocks.Record())
        //    {
        //        this.fileLoad.FileOpened += null;
        //        LastCall.IgnoreArguments();
        //        openedEvent = LastCall.GetEventRaiser();

        //        //presenter should notify view of the file parse error
        //        Expect.Call(this.fileLoad.FilePath).Return("fileName");
        //        //Expect.Call(this.fileParser.ParseGenotypeFile("fileName")).Throw(new Exception("Insufficient permissions"));

        //        this.view.DisplayError("Unable to open genotype file: Insufficient permissions");
        //    }

        //    using (this.mocks.Playback())
        //    {
        //        var presenter = this.CreatePresenter();
        //        openedEvent.Raise(null, null);
        //        Assert.IsTrue(this.loginGuard.WasCalled);
        //    }
        //}

        //[TestMethod]
        //[Ignore]    //fix file parsing
        //public void GenotypeFileOpened_ServiceCallFails()
        //{
        //    IEventRaiser openedEvent;

        //    using (this.mocks.Record())
        //    {
        //        this.fileLoad.FileOpened += null;
        //        LastCall.IgnoreArguments();
        //        openedEvent = LastCall.GetEventRaiser();

        //        //presenter should try to parse the given file contents, and then notify the view when the service call fails
        //        Expect.Call(this.fileLoad.FilePath).Return("fileName");

        //        IndividualGenotypeCollection genotypes = new IndividualGenotypeCollection();
        //        genotypes.Markers.Add("marker1");
        //        genotypes.Markers.Add("marker2");
        //        genotypes.Markers.Add("marker3");

        //        //Expect.Call(this.fileParser.ParseGenotypeFile("fileName")).Return(genotypes);
        //        Expect.Call(this.snpService.FilterUnavailableMarkers(genotypes.Markers)).Throw(new ServiceException("Service unavailable"));

        //        this.view.DisplayError("Unable to get marker information from the SNP service: Service unavailable");
        //    }

        //    using (this.mocks.Playback())
        //    {
        //        var presenter = this.CreatePresenter();
        //        openedEvent.Raise(null, null);
        //        Assert.IsTrue(this.loginGuard.WasCalled);
        //    }
        //}

        //#endregion

        //#region Filter List Opened

        //[TestMethod]
        //public void FilterListOpenedFileSelectedParseSucceeds()
        //{
        //    IEventRaiser openEvent;

        //    using (this.mocks.Record())
        //    {
        //        this.view.FilterListOpened += null;
        //        LastCall.IgnoreArguments();
        //        openEvent = LastCall.GetEventRaiser();

        //        this.filterListDialog.Open();
        //        LastCall.Return<string>("someFilePath");

        //        ICollection<string> watchList = new[] { "marker1", "marker2" };
        //        Expect.Call(this.watchListParser.Parse("someFilePath")).Return(watchList);

        //        this.model.WatchList = watchList;
        //    }

        //    using (this.mocks.Playback())
        //    {
        //        var presenter = this.CreatePresenter();
        //        openEvent.Raise(null, null);
        //    }
        //}

        //[TestMethod]
        //public void FilterListOpenedFileSelectedParseFails()
        //{
        //    IEventRaiser openEvent;

        //    using (this.mocks.Record())
        //    {
        //        this.view.FilterListOpened += null;
        //        LastCall.IgnoreArguments();
        //        openEvent = LastCall.GetEventRaiser();

        //        this.filterListDialog.Open();
        //        LastCall.Return<string>("someFilePath");

        //        ICollection<string> watchList = new[] { "marker1", "marker2" };
        //        Expect.Call(this.watchListParser.Parse("someFilePath")).Throw(new FileParseException("Invalid file format"));

        //        this.view.DisplayError("Error opening watch list: Invalid file format");
        //    }

        //    using (this.mocks.Playback())
        //    {
        //        var presenter = this.CreatePresenter();
        //        openEvent.Raise(null, null);
        //    }
        //}

        //[TestMethod]
        //public void FilterListOpenedCancelled()
        //{
        //    IEventRaiser openEvent;

        //    using (this.mocks.Record())
        //    {
        //        this.view.FilterListOpened += null;
        //        LastCall.IgnoreArguments();
        //        openEvent = LastCall.GetEventRaiser();

        //        //file dialog should be opened and return null to indicate the user cancelled
        //        this.filterListDialog.Open();
        //        LastCall.Return<string>(null);
        //    }

        //    using (this.mocks.Playback())
        //    {
        //        var presenter = this.CreatePresenter();
        //        openEvent.Raise(null, null);
        //    }
        //}

        //#endregion

        //#region Missing Marker Selected

        //[TestMethod]
        //public void MissingMarkerSelectedTestNotNull()
        //{
        //    IEventRaiser selectedEvent;

        //    using (this.mocks.Record())
        //    {
        //        this.view.MissingMarkerSelected += null;
        //        LastCall.IgnoreArguments();
        //        selectedEvent = LastCall.GetEventRaiser();

        //        //presenter should open the selected marker in the marker edit form
        //        Expect.Call(this.view.SelectedMarker).Return(new MissingMarker("markerName"));
        //        this.markerEdit.LoadMarker("markerName");
        //    }

        //    using (this.mocks.Playback())
        //    {
        //        var presenter = this.CreatePresenter();
        //        selectedEvent.Raise(null, null);
        //    }
        //}

        //[TestMethod]
        //public void MissingMarkerSelectedTestNull()
        //{
        //    IEventRaiser selectedEvent;

        //    using (this.mocks.Record())
        //    {
        //        this.view.MissingMarkerSelected += null;
        //        LastCall.IgnoreArguments();
        //        selectedEvent = LastCall.GetEventRaiser();

        //        //presenter should open the selected marker in the marker edit form
        //        Expect.Call(this.view.SelectedMarker).Return(null);
        //        this.markerEdit.LoadMarker((SnpMarkerInfo)null);
        //    }

        //    using (this.mocks.Playback())
        //    {
        //        var presenter = this.CreatePresenter();
        //        selectedEvent.Raise(null, null);
        //    }
        //}

        //#endregion

        //#region Model Updated

        //[TestMethod]
        //public void ModelUpdatedTest()
        //{
        //    IEventRaiser listChangedEvent;

        //    using (this.mocks.Record())
        //    {
        //        this.model.ListChanged += null;
        //        LastCall.IgnoreArguments();
        //        listChangedEvent = LastCall.GetEventRaiser();

        //        var missingMarkers = new[] { new MissingMarker("marker1", false), new MissingMarker("marker2", false) };
        //        Expect.Call(this.model.Items).Return(missingMarkers);
        //        this.view.MissingMarkers = missingMarkers;
        //    }

        //    using (this.mocks.Playback())
        //    {
        //        var presenter = this.CreatePresenter();
        //        listChangedEvent.Raise(null, null);
        //    }
        //}

        //#endregion

        //#region Marker Edit Completed

        //[TestMethod]
        //public void MarkerEditCompletedTest()
        //{
        //    IEventRaiser editCompletedEvent;

        //    using (this.mocks.Record())
        //    {
        //        this.markerEdit.MarkerUpdated += null;
        //        LastCall.IgnoreArguments();
        //        editCompletedEvent = LastCall.GetEventRaiser();

        //        //if information for an unfound marker is added by the user, it should be removed from the model since it is no longer missing
        //        Expect.Call(this.model.RemoveMarker("markerName")).Return(true);
        //    }

        //    using (this.mocks.Playback())
        //    {
        //        var presenter = this.CreatePresenter();
        //        editCompletedEvent.Raise(null, new MarkerUpdatedEventArgs(new SnpMarkerInfo() { MarkerName = "markerName", RsNumber = "123", Chromosome = "15", Position = "343463454" }));
        //    }
        //}

        //#endregion

        //#endregion

        //#region Private Methods

        //private OpenGenotypeFilePresenter CreatePresenter()
        //{
        //    return new OpenGenotypeFilePresenter(this.model, this.view, this.fileLoad, this.filterListDialog, this.markerEdit, this.loginGuard, this.snpService, this.watchListParser);
        //}

        //#endregion
    }
}
